package cn.bincker.mycaptcha.basic.impl;

import cn.bincker.mycaptcha.basic.AnswerStorage;
import cn.bincker.mycaptcha.basic.entity.MyAnswer;
import cn.bincker.mycaptcha.basic.properties.MyCaptchaProperties;

import javax.servlet.http.HttpServletRequest;
import java.util.Optional;

public abstract class SessionAnswerStorage<T extends MyAnswer> implements AnswerStorage<T> {
    private static final String SESSION_KEY_ANSWER_SUFFIX = ".SESSION_ANSWER_KEY";
    private static final String SESSION_KEY_EXPIRED_TIME_SUFFIX = ".SESSION_EXPIRED_TIME_KEY";

    private final MyCaptchaProperties properties;

    public SessionAnswerStorage(MyCaptchaProperties properties) {
        this.properties = properties;
    }

    @Override
    public void store(HttpServletRequest request, MyAnswer answer) {
        var session = request.getSession();
        session.setAttribute(getName() + SESSION_KEY_ANSWER_SUFFIX, answer);
        session.setAttribute(getName() + SESSION_KEY_EXPIRED_TIME_SUFFIX, System.currentTimeMillis() + properties.getSurvivalTime());
    }

    @Override
    public Optional<T> getAndRemove(HttpServletRequest request) {
        var session = request.getSession(false);
        if(session == null) return Optional.empty();
        var expiredTime = (Long) session.getAttribute(getName() + SESSION_KEY_EXPIRED_TIME_SUFFIX);
        if(expiredTime == null || expiredTime < System.currentTimeMillis()) return Optional.empty();
        //noinspection unchecked
        var result = (T) session.getAttribute(getName() + SESSION_KEY_ANSWER_SUFFIX);
        session.removeAttribute(getName() + SESSION_KEY_EXPIRED_TIME_SUFFIX);
        session.removeAttribute(getName() + SESSION_KEY_ANSWER_SUFFIX);
        return Optional.ofNullable(result);
    }

    public abstract String getName();
}
